package com.jinyuanchun.learnjava;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class Genericity {
    public static void main(String[] args) throws Exception {
        Car1 car = new Car1("tom","red");
        Person1 person = new Person1("zhangsan",23,"18899770523","qq@qq.com");

        Obj2Map<Car1> test1 = new Obj2Map<>();
        Map<String,Object> hash1 = new HashMap<>();
        hash1 = test1.object2hash(car,hash1);
        for(String key: hash1.keySet()){
            Object value = hash1.get(key);
            System.out.println("key="+key+"\tvalue="+value);
        }
    }
}

class Obj2Map<T> {
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public <T,K,V> Map<String, Object> object2hash(T bean,Map<String,Object> mp) throws Exception,IllegalAccessException{
        if (bean == null){return null;}
        try{
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for(PropertyDescriptor property : propertyDescriptors){
                String key = property.getName();
                if(!key.equals("class")){
                    Method getter = property.getReadMethod();
                    Object value;
                    value = getter.invoke(bean);
                    mp.put(key,value);
                }
            }
        } catch (IntrospectionException e){
            e.printStackTrace();
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e ){
            e.printStackTrace();
        }
        return mp;


//        Field[] fields= bean.getClass().getDeclaredFields();
//        for(int i=0;i<fields.length;i++){
//            String attributeName=fields[i].getName();
//            System.out.println(attributeName);
//            attributeName = attributeName.toLowerCase();  //将key置为小写，默认为对象的属性
//            try {
//                // 获取原来的访问控制权限
//                boolean accessFlag = fields[i].isAccessible();
//                // 修改访问控制权限
//                fields[i].setAccessible(true);
//                // 获取在对象f中属性fields[i]对应的对象中的变量
//                Object o = fields[i].get(t);
//                if (o != null)
//                    mp.put(attributeName, o);
//                // System.out.println("传入的对象中包含一个如下的变量：" + varName + " = " + o);
//                // 恢复访问控制权限
//                fields[i].setAccessible(accessFlag);
//            } catch (IllegalArgumentException ex) {
//                ex.printStackTrace();
//            } catch (IllegalAccessException ex) {
//                ex.printStackTrace();
//            }
//        }
//        return mp;
    }
}

class Car1 {
    private String name;
    private String color;

    public Car1(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

class Person1 {
    private String name;
    private Integer age;
    private String telephone;
    private String email;

    public Person1(String name, Integer age, String telephone, String email) {
        this.name = name;
        this.age = age;
        this.telephone = telephone;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
